version: "3.8"
networks:
  webgateway:
    external: true
services:

  nginx:
    container_name: nginx
    image: nginx:latest
    command: '/bin/sh -c ''while :; do sleep 336h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'''
    depends_on:
      - backend
    volumes:
      - ./docker/nginx/nginx.conf:/etc/nginx/sites-available/default.conf
      - ./docker/nginx/certbot/conf:/etc/letsencrypt
      - ./docker/nginx/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
    deploy:
      placement:
        constraints:
          - node.role == manager
        restart_policy:
          condition: on-failure
          delay: 5s
          max_attempts: 3
          window: 120s
        update_config:
          parallelism: 2
          delay: 10s
          order: stop-first
        rollback_config:
          parallelism: 2
          delay: 10s
          order: stop-first
        resources:
          limits:
            cpus: '0.20'
            memory: 100M
          reservations:
            cpus: '0.05'
            memory: 20M
        ports:
          - 80:80
          - 443:443


  certbot:
    container_name: certbot
    entrypoint:  "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 118h & wait $${!}; done;'"
    image: certbot/certbot
    volumes:
      - ./docker/nginx/certbot/conf:/etc/letsencrypt
      - ./docker/nginx/certbot/www:/var/www/certbot
    deploy:
      placement:
        constraints:
          - node.role == manager
        restart_policy:
          condition: on-failure
          delay: 5s
          max_attempts: 3
          window: 120s
        update_config:
          parallelism: 2
          delay: 10s
          order: stop-first
        rollback_config:
          parallelism: 2
          delay: 10s
          order: stop-first
        resources:
          limits:
            cpus: '0.20'
            memory: 100M
          reservations:
            cpus: '0.05'
            memory: 20M
        ports:
          - 80:80
          - 443:443

  backend:
    image: backend:latest-prod
    networks:
      - webgateway
      - default
    env_file:
      - .prod.env
    build:
      context: .
      dockerfile: backend.Dockerfile
    ports:
      - 8000:8000
    volumes:
      - ./app:/app
    deploy:
      mode: replicated
      replicas: 4
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      resources:
        limits:
          cpus: '0.50'
          memory: 150M
        reservations:
          cpus: '0.20'
          memory: 40M

  celery:
    image: celery:latest-prod
    env_file:
      - .prod.env
    build:
      context: .
      dockerfile: celery.Dockerfile
    ports:
      - 8000
    depends_on:
      - backend
    volumes:
      - ./app:/app
    deploy:
      mode: replicated
      replicas: 4
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      resources:
        limits:
          cpus: '0.50'
          memory: 200M
        reservations:
          cpus: '0.20'
          memory: 50M

  flower:
    image: flower:latest-prod
    container_name: flower
    networks:
      - webgateway
      - default
    build:
      context: .
      dockerfile: flower.Dockerfile
    env_file:
      - .prod.env
    volumes:
      - ./app:/app
    ports:
      - 8888:8888
    deploy:
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      resources:
        limits:
          cpus: '0.20'
          memory: 50M
        reservations:
          cpus: '0.05'
          memory: 20M

  redis:
    image: redis
    container_name: redis
    env_file:
      - .prod.env
    command: [ "redis-server", "/docker/redis/redis.conf" ]
    ports:
      - 6379:6379
    volumes:
      - ./docker/redis/redis-data:/data/bases
      - ./docker/redis/redis.conf:/docker/redis/redis.conf
      - ./docker/redis/log:/docker/redis/log
    deploy:
      placement:
        constraints:
          - "node.labels.type==queue"
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first

  rabbitmq:
    image: rabbitmq:3.8.4-management
    container_name: rabbitmq
    networks:
      - webgateway
      - default
    env_file:
      - .prod.env
    volumes:
      - ./docker/rabbitmq/etc/:/etc/rabbitmq/
      - ./docker/rabbitmq/data/:/var/lib/rabbitmq/
      - ./docker/rabbitmq/logs/:/var/log/rabbitmq/
    ports:
      - 5672:5672
      - 15672:15672
    deploy:
      placement:
        constraints:
          - "node.labels.type==queue"
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first


  db:
    image: postgres:12
    networks:
      - webgateway
      - default
    volumes:
      - ./docker/postgres/:/var/lib/postgresql/data/pgdata
    env_file:
      - .prod.full.env
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
    deploy:
      constraints:
        - node.role == manager
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first

  pgadmin:
    image: dpage/pgadmin4
    depends_on:
      - db
    env_file:
      - .prod.full.env
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first